#include "Timer.h"
#include <math.h>


Timer::Timer(void)
{
	// Check for Performance Counter and setup time scale
	if (QueryPerformanceFrequency((LARGE_INTEGER *)&m_PerfFreq)) // Tra ve so luong couter 1 giay
	{
		m_PerfHardware = true;
		QueryPerformanceCounter((LARGE_INTEGER *)&m_LastTime); // Lay gia tri couter
		m_TimeScale = 1.0f/m_PerfFreq; // Tinh 1 counter = bao nhieu giay
	}
	else
	{
		// No Performance Counter, using timeGetTime
		m_PerfHardware = false;
		m_LastTime = timeGetTime();
		m_TimeScale = 0.001f;
	}

	// Clear values
	m_FrameRate = 0;
	m_CurrentTime = 0;
	m_TimeElased = 0.0f;
	m_FPSFrameCount = 0;
	m_FPSTimeElased = 0.0f;
	m_FrameTimeCount = 0;

}

Timer::~Timer(void)
{

}

void Timer::Tick(float fLockFPS)
{
	float fTimeElased = 0.0f;

	// Check for Performance Counter
	if (m_PerfHardware)
	{
		QueryPerformanceCounter((LARGE_INTEGER *)&m_CurrentTime);		
	}
	else
	{
		m_CurrentTime = timeGetTime();
	}
	
	// Calculate elased time 
	fTimeElased = (m_CurrentTime - m_LastTime) * m_TimeScale;

	// Lock Frame Rate 
	if (fLockFPS > 0.0f)
	{
		while (fTimeElased < 1.0f/fLockFPS)
		{
			if (m_PerfHardware)
			{
				QueryPerformanceCounter((LARGE_INTEGER *)&m_CurrentTime);		
			}
			else
			{
				m_CurrentTime = timeGetTime();
			}

			fTimeElased = (m_CurrentTime - m_LastTime) * m_TimeScale;
		}
	}

	// Save last time for next tick
	m_LastTime = m_CurrentTime;

	/*if (fabsf(fTimeElased - m_TimeElased) < 1.0f)
	{
		memmove(&m_FrameTime[1], m_FrameTime, (MAX_COUNT-1)*sizeof(float));
		m_FrameTime[0] = fTimeElased;
		if (m_FrameTimeCount < MAX_COUNT) 
			m_FrameTimeCount++;
	}*/

	// Calculate FPS
	m_FPSFrameCount++;
	m_FPSTimeElased += fTimeElased;
	if (m_FPSTimeElased >= 1.0f)
	{
		m_FrameRate = m_FPSFrameCount;
		m_FPSFrameCount = 0;
		m_FPSTimeElased = 0.0f;
	}

	// Calculate Time Per Second
	/*m_TimeElased = 0;
	for (short i = 0; i<m_FrameTimeCount; i++)
		m_TimeElased += m_FrameTime[i];
	if (m_FrameTimeCount > 0)
		m_TimeElased = m_TimeElased/m_FrameTimeCount;*/
	m_TimeElased = fTimeElased;
	// Calculate game time
}

float Timer::GetTimeElased()
{
	return m_TimeElased;
}

unsigned short Timer::GetFrameRate(LPTSTR lpszFrameRate)
{
	if (lpszFrameRate != NULL)
		_itot(m_FrameRate, lpszFrameRate, 10);

	return m_FrameRate;
}

float Timer::GetGameTime()// millisecond
{
	return this->m_LastTime * this->m_TimeScale * 1000;
}